package com.code2roc.jarmanage.servlet.depoly;

import com.code2roc.jarmanage.db.DepolyUploadVersionDB;
import com.code2roc.jarmanage.db.ProjectDB;
import com.code2roc.jarmanage.model.DepolyUploadVersionDO;
import com.code2roc.jarmanage.model.ProjectDO;
import com.code2roc.jarmanage.model.Result;
import com.code2roc.jarmanage.util.*;

import javax.servlet.ServletException;
import javax.servlet.annotation.MultipartConfig;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.Part;
import java.io.File;
import java.io.FilenameFilter;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.nio.file.attribute.BasicFileAttributes;
import java.nio.file.attribute.FileTime;
import java.util.Arrays;
import java.util.Comparator;
import java.util.List;

@MultipartConfig
public class UploadServlet extends HttpServlet {

    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        Result result = Result.okResult();
        String projectID = req.getParameter("projectID");
        int chunkCount = ConvertUtil.convert2Int(req.getParameter("chunkCount"));
        int chunkIndex = ConvertUtil.convert2Int(req.getParameter("chunkIndex"));
        Part file = req.getPart("file");
        ProjectDO entity = ProjectDB.selectOne(projectID);
        String chunkPath = "";
        String filePath = "";
        String backUpFilePath = "";
        String versionName = "";
        String versionFilePath = "";
        if (StringUtil.isEmpty(entity.getDepolyType())) {
            //jar
            chunkPath = entity.getJarPackagePath() + File.separator + "chunk";
            filePath = entity.getJarPackagePath() + File.separator + entity.getServiceName() + ".jar";
            backUpFilePath = entity.getJarPackagePath() + File.separator + "backup-" + CommonUtil.getDateTagToSecond2() + ".jar";
            versionName = "upload-" + CommonUtil.getDateTagToSecond2();
            versionFilePath = entity.getJarPackagePath() + File.separator + "depolyversion" + File.separator + versionName + ".jar";
            FileUtil.initfloderPath(entity.getJarPackagePath() + File.separator + "depolyversion");
        } else {
            //war
            chunkPath = entity.getJarPackagePath() + File.separator + "webapps" + File.separator + "chunk";
            filePath = entity.getJarPackagePath() + File.separator + "webapps" + File.separator + entity.getServiceName() + ".war";
            backUpFilePath = entity.getJarPackagePath() + File.separator + "webapps" + File.separator + "backup-" + CommonUtil.getDateTagToSecond2() + ".war";
            versionName = "upload-" + CommonUtil.getDateTagToSecond2();
            versionFilePath = entity.getJarPackagePath() + File.separator + "webapps" + File.separator + "depolyversion" + File.separator + versionName + ".war";
            FileUtil.initfloderPath(entity.getJarPackagePath() + File.separator + "webapps" + File.separator + "depolyversion");
        }
        FileUtil.initfloderPath(chunkPath);
        String chunkFilePath = chunkPath + File.separator + "chunk-" + chunkIndex;
        FileUtil.uploadFile(FileUtil.convertStreamToByte(file.getInputStream()), chunkFilePath);
        if (chunkIndex == chunkCount - 1) {
            if (new File(filePath).exists()) {
                FileUtil.copyFile(filePath, backUpFilePath);
                FileUtil.delete(filePath);
            }
            File chunkFileDir = new File(chunkPath);
            List<File> chunkFileList = Arrays.asList(chunkFileDir.listFiles());
            chunkFileList.sort(new Comparator<File>() {
                @Override
                public int compare(File o1, File o2) {
                    int result = 1;
                    try {
                        int sort1 = ConvertUtil.convert2Int(o1.getName().replace("chunk-", ""));
                        int sort2 = ConvertUtil.convert2Int(o2.getName().replace("chunk-", ""));
                        result = sort1 - sort2;
                    } catch (Exception e) {
                        LogUtil.error(e);
                    }
                    return result;
                }
            });
            FileUtil.merageFile(chunkFileList, filePath);
            FileUtil.delete(chunkPath);

            DepolyUploadVersionDO versionDO = new DepolyUploadVersionDO();
            versionDO.setVersionID(CommonUtil.getNewGuid());
            versionDO.setForceKeep("0");
            versionDO.setProjectID(projectID);
            versionDO.setVersionName(versionName);
            versionDO.setVersionPath(versionFilePath);
            versionDO.setVersionRemark("");
            DepolyUploadVersionDB.insert(versionDO);
            FileUtil.copyFile(filePath, versionFilePath);

            String depolyPath = entity.getJarPackagePath();
            File deployDir = new File(depolyPath);
            List<File> backUpFileList = Arrays.asList(deployDir.listFiles(new FilenameFilter() {
                @Override
                public boolean accept(File dir, String name) {
                    return name.startsWith("backup-");
                }
            }));
            backUpFileList.sort(new Comparator<File>() {
                @Override
                public int compare(File o1, File o2) {
                    int result = 1;
                    try {
                        BasicFileAttributes fileInfo1 = Files.readAttributes(Paths.get(o1.getAbsolutePath()), BasicFileAttributes.class);
                        BasicFileAttributes fileInfo2 = Files.readAttributes(Paths.get(o2.getAbsolutePath()), BasicFileAttributes.class);
                        FileTime fileTime1 = fileInfo1.creationTime();
                        FileTime fileTime2 = fileInfo2.creationTime();
                        result = fileTime2.compareTo(fileTime1);
                    } catch (Exception e) {
                        LogUtil.error(e);
                    }
                    return result;
                }
            });
            for (int i = 0; i < backUpFileList.size(); i++) {
                if (i > ConvertUtil.convert2Int(ConfigUtil.getConfigValue("backupcount")) - 1) {
                    backUpFileList.get(i).delete();
                }
            }

        }

        List<DepolyUploadVersionDO> versionDOList = DepolyUploadVersionDB.selectRollList(projectID);
        for (int i = 0; i < versionDOList.size(); i++) {
            if (i > ConvertUtil.convert2Int(ConfigUtil.getConfigValue("uploadcount")) - 1) {
                DepolyUploadVersionDO versionDO = versionDOList.get(i);
                FileUtil.delete(versionDO.getVersionPath());
                DepolyUploadVersionDB.delete(versionDO.getVersionID());
            }
        }

        resp.getWriter().println(result.toString());
    }
}
